package com.tianji.learning.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.cache.UserCache;
import com.tianji.api.client.remark.RemarkClient;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.constants.MqConstants;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.dto.ReplyDTO;
import com.tianji.learning.domain.po.InteractionQuestion;
import com.tianji.learning.domain.po.InteractionReply;
import com.tianji.learning.domain.query.ReplyPageQuery;
import com.tianji.learning.domain.vo.ReplyVO;
import com.tianji.learning.enums.QuestionStatus;
import com.tianji.learning.mapper.InteractionReplyMapper;
import com.tianji.learning.mq.message.SignInMessage;
import com.tianji.learning.service.IInteractionQuestionService;
import com.tianji.learning.service.IInteractionReplyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 互动问题的回答或评论 服务实现类
 * </p>
 *
 * @author hrz
 * @since 2025-08-29
 */
@Service
@RequiredArgsConstructor
public class InteractionReplyServiceImpl extends ServiceImpl<InteractionReplyMapper, InteractionReply> implements IInteractionReplyService {
    private final IInteractionQuestionService questionService;
    private final UserCache userCache;
    private final RemarkClient remarkClient;
    private final RabbitMqHelper rabbitMqHelper;

    @Override
    public void saveReply(ReplyDTO replyDTO) {
        Long questionId = replyDTO.getQuestionId(); //问题id
        Long targetReplyId = replyDTO.getTargetReplyId(); //目标评论id
        Long answerId = replyDTO.getAnswerId(); // 上级回答id
        InteractionReply interactionReply =
                BeanUtils.copyBean(replyDTO, InteractionReply.class);
        interactionReply.setCreateTime(LocalDateTime.now());
        interactionReply.setUpdateTime(LocalDateTime.now());
        interactionReply.setLikedTimes(0);
        interactionReply.setReplyTimes(0);
        interactionReply.setUserId(UserContext.getUser());
        this.save(interactionReply); // 插入回答
        if (answerId != null && answerId != 0) { //说明是对回答的评论
            //让该回答的评论数加一
            InteractionReply interactionReply2 =
                    this.lambdaQuery()
                            .eq(InteractionReply::getId, answerId)
                            .one();
            interactionReply2.setReplyTimes(interactionReply.getReplyTimes() + 1);
            this.updateById(interactionReply2);
        } else if (targetReplyId == null || targetReplyId == 0) {
            //此时说明是问题的回答
            //更新问题的最后回答时间和回答次数
            InteractionQuestion q = questionService.lambdaQuery()
                    .eq(InteractionQuestion::getId, questionId).one();
            q.setAnswerTimes(q.getAnswerTimes() + 1);
            q.setLatestAnswerId(interactionReply.getId());
            if (replyDTO.getIsStudent()) {
                //是学生的互动,就要标记为未查看
                q.setStatus(QuestionStatus.UN_CHECK.getValue());
            } else {
                //是老师的互动,就要标记为已查看
                q.setStatus(QuestionStatus.CHECKED.getValue());
            }
            questionService.updateById(q);
            //如果是对问题的回答,就要给予5分的积分奖励,发送消息给积分服务
            rabbitMqHelper.send(
                    MqConstants.Exchange.LEARNING_EXCHANGE,
                    MqConstants.Key.WRITE_REPLY,
                    SignInMessage.of(UserContext.getUser(),5)
            );
        } //注意不可能存在answerId == 0 && targetReplyId != 0,因为评论一定会出现在回答下面
    }

    @Override
    public PageDTO<ReplyVO> pagequery(ReplyPageQuery replyPageQuery) {
        return pageMethod(replyPageQuery, false);
    }

    @Override
    public PageDTO<ReplyVO> Adminpagequery(ReplyPageQuery replyPageQuery) {
        return pageMethod(replyPageQuery, true);
    }

    @Override
    public void hideReply(Long replyId, boolean hidden) {
        //注意,如果隐藏的是回答,回答下面的评论都要一并隐藏
        //1.先查询回答是否存在 - 可能被用户自己删除了
        InteractionReply interactionReply = this.lambdaQuery()
                .eq(InteractionReply::getId, replyId)
                .one();
        if (interactionReply == null) {
            throw new IllegalArgumentException("回复不存在");
        }
        //2.存在的话判断reply的类型
        if (interactionReply.getTargetReplyId() == 0) {
            //说明是对问题的回答 - 此时要查找出该回答下的所有评论
            if (hidden) {
                //说明此时要隐藏
                //将该回答下的所有评论都隐藏
                this.lambdaUpdate()
                        .eq(InteractionReply::getAnswerId, replyId)
                        .set(InteractionReply::getHidden, true);
                //将该回答也隐藏
                this.lambdaUpdate()
                        .eq(InteractionReply::getId, replyId)
                        .set(InteractionReply::getHidden, true);
            } else {
                //此时是显示
                //将该回答下的所有评论都显示
                this.lambdaUpdate()
                        .eq(InteractionReply::getAnswerId, replyId)
                        .set(InteractionReply::getHidden, false);
                //将该回答也显示
                this.lambdaUpdate()
                        .eq(InteractionReply::getId, replyId)
                        .set(InteractionReply::getHidden, false);
            }
        } else {
            //说明是对某一条评论的回复
            //此时要隐藏该条评论 - 对该评论的回复不隐藏
            if (hidden) {
                this.lambdaUpdate()
                        .eq(InteractionReply::getId, interactionReply.getId())
                        .set(InteractionReply::getHidden, true);
            } else {
                this.lambdaUpdate()
                        .eq(InteractionReply::getId, interactionReply.getId())
                        .set(InteractionReply::getHidden, false);
            }
        }
    }


    private PageDTO<ReplyVO> pageMethod(ReplyPageQuery replyPageQuery, boolean isAdmin) {
        Long answerId = replyPageQuery.getAnswerId();
        Long questionId = replyPageQuery.getQuestionId();
        List<ReplyVO> result = new ArrayList<>();
        //1.根据问题或者回答id去分页查询回复
        Page<InteractionReply> page = null;
        if (isAdmin) { //如果是管理端,就不管是否隐藏,都查询出来
            page = this.lambdaQuery()
                    .eq(InteractionReply::getQuestionId, questionId)
                    .eq(answerId != 0, InteractionReply::getAnswerId, answerId)
                    .page(replyPageQuery.toMpPageDefaultSortByCreateTimeDesc());
        } else {
            page = this.lambdaQuery()
                    .eq(InteractionReply::getQuestionId, questionId)
                    .eq(answerId != 0, InteractionReply::getAnswerId, answerId)
                    .eq(InteractionReply::getHidden, false)
                    .page(replyPageQuery.toMpPageDefaultSortByCreateTimeDesc());
        }
        List<InteractionReply> records = page.getRecords();
        //todo 当前用户是否点过赞
        List<Long> collect = records.
                stream().map(InteractionReply::getId).collect(Collectors.toList());
        Set<Long> longs = remarkClient.queryLiked(collect); //点过赞的ID集合(HashSet)
        //2.根据回答是否匿名去查询个人信息
        //搞一个缓存，key是用户id，value是用户信息
        for (InteractionReply record : records) {
            ReplyVO replyVO = BeanUtils.copyBean(record, ReplyVO.class);
            replyVO.setLiked(false); //先设置为没点赞的状态
            if (longs.contains(record.getId())) {
                //如果点赞过的HashSet中有该记录的回答ID,说明用户点过赞
                replyVO.setLiked(true);
            }
            if (record.getTargetReplyId() == 0) {
                //如果TargetReplyId==0,说明是对问题的回答
                if (record.getAnonymity()) {
                    //匿名就跳过
                    continue;
                }
                Long userId = record.getUserId(); //回答者id
                // 从缓存中查询用户信息
                UserDTO userDTO = userCache.getUser(userId);
                replyVO.setUserIcon(userDTO.getIcon());
                replyVO.setUserType(userDTO.getType());
                replyVO.setUserName(userDTO.getName());
            } else {
                //说明是对某个人的评论的回复
                if (record.getAnonymity()) {
                    //匿名就跳过
                    continue;
                }
                Long userId = record.getUserId(); //回复者id
                Long targetUserId = record.getTargetUserId();//被回复者id
                // 从缓存中查询用户信息
                UserDTO userDTO = userCache.getUser(userId); //回复者信息
                UserDTO targetUserDTO = userCache.getUser(targetUserId); //被回复者信息
                replyVO.setUserIcon(userDTO.getIcon());
                replyVO.setUserType(userDTO.getType());
                replyVO.setUserName(userDTO.getName());
                replyVO.setTargetUserName(targetUserDTO.getName());
            }
            result.add(replyVO);
        }
        return new PageDTO<>(page.getTotal(), page.getPages(), result);
    }
}
